package edu.uc.labs.MobilePrinting.GUI;

import edu.uc.labs.MobilePrinting.Configurator;
import edu.uc.labs.MobilePrinting.PrintUtils.Printer;
import edu.uc.labs.MobilePrinting.PrintUtils.PrinterCache;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import org.apache.log4j.Logger;

/**
 * 
 * @author Matt Silbernagel
 */
public class SysTray {

	private TrayIcon trayIcon = null;;
	private String IMG;
	private ArrayList<Printer> printers = null;
	private PopupMenu popup = new PopupMenu();
	private PopupMenu updating = new PopupMenu();
	private SystemTray tray;
	private Image image;

	private Logger logger = Configurator.LOGGER;
	private String cache_dir = Configurator.CACHEDIR;

	public SysTray() {
		if (Configurator.OS.startsWith("Win")) {
			IMG = cache_dir + Configurator.ICONS + Configurator.DELIM
					+ Configurator.TRAYICON;
		} else if (Configurator.OS.equalsIgnoreCase("Mac OS X")) {
			IMG = cache_dir + Configurator.ICONS + Configurator.DELIM
					+ Configurator.TRAYICON_MAC;
		} else {
			IMG = cache_dir + Configurator.ICONS + Configurator.DELIM
					+ Configurator.TRAYICON_NIX;
		}
		if (SystemTray.isSupported()) {
			tray = SystemTray.getSystemTray();
			image = Toolkit.getDefaultToolkit().getImage(IMG);
			MouseListener mouseListener = new MouseListener() {

				public void mouseClicked(MouseEvent e) {
					// System.out.println("Tray Icon - Mouse clicked!");
				}

				public void mousePressed(MouseEvent e) {
					// System.out.println("Tray Icon - Mouse pressed!");
				}

				public void mouseReleased(MouseEvent e) {
					// System.out.println("Tray Icon - Mouse released!");
				}

				public void mouseEntered(MouseEvent e) {
					// System.out.println("Tray Icon - Mouse entered");
				}

				public void mouseExited(MouseEvent e) {
					// System.out.println("Tray Icon - Mouse exited");
				}

			};

			MenuItem noPrinters = new MenuItem("No Printers Accessible");
			popup.add(noPrinters);
			popup.addSeparator();
			this.getDefaultSet();

			MenuItem nowInUpdate = new MenuItem("Updating");
			updating.add(nowInUpdate);
			updating.addSeparator();
			this.getDefaultSet();

			trayIcon = new TrayIcon(image, "Mobile Printing", popup);

			ActionListener actionListener = new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					/*
					 * trayIcon.displayMessage("Action Event",
					 * "An Action Event Had Been Performed!",
					 * TrayIcon.MessageType.NONE);
					 */
					// Open the preferences pane...
					// UIManager.put("swing.boldMetal", Boolean.FALSE);
					// TabbedPane.createAndShowGUI();
				}
			};

			trayIcon.setImageAutoSize(true);
			logger.debug("Image size = " + trayIcon.getSize());
			trayIcon.addActionListener(actionListener);
			trayIcon.addMouseListener(mouseListener);

			try {
				tray.add(trayIcon);
			} catch (AWTException e) {
				logger.error("TrayIcon could not be added. ");
			}
		} else {
			logger.debug("System Tray is not supported");
		}
	}

	public void add(ArrayList<Printer> p) {
		printers = p;
		Printer cache = null;
		if (Configurator.getZone() != null) {
			try {
				cache = PrinterCache.getCache(Configurator.getZone());
				logger
						.debug("the default printer should be "
								+ cache.getName());
			} catch (NullPointerException ex) {
			}
		}
		// Remove everything from the popup menu
		// so we can rebuild it.
		popup.removeAll();

		if (printers.isEmpty()) {
			MenuItem noPrinters = new MenuItem("No Printers Accessible");
			// TODO Un-install the printer if there are no printers accessible
			noPrinters.setEnabled(false);
			popup.add(noPrinters);
		} else {

			// Loop through the list of available printers
			for (final Printer prn : printers) {
				final CheckboxMenuItem c = new CheckboxMenuItem(prn.getName());

				ItemListener prnItemListener = new ItemListener() {

					@Override
					public void itemStateChanged(ItemEvent e) {
						// Do the work as long as
						// this isn't the currently active
						// printer
						if (!prn.isActive()) {
							// Set all printers in the menu unactive
							setAllPrintersInactive();
							// Then set this one to active
							prn.setActive(true);
							c.setState(true);
							if (prn.InstallPrinter()) {
								trayIcon
										.displayMessage(
												"Success",
												"Your printer is installed and ready to use",
												TrayIcon.MessageType.NONE);
							} else {
								trayIcon
										.displayMessage(
												"Failed to install printer",
												"Unable to install the printer, please check the logs",
												TrayIcon.MessageType.ERROR);
							}
						} else {
							c.setState(true);
						}
					}
				};

				c.addItemListener(prnItemListener);
				popup.add(c);
			}
		}

		popup.addSeparator();
		this.getDefaultSet();

		// Loop through the checklist
		// and install the default printer if
		// there is one
		if ((cache != null) && (!cache.isEmpty())) {
			// If there is a Printer in cache
			// then execute the loop
			for (int i = 0; i < popup.getItemCount(); i++) {
				try {
					CheckboxMenuItem mi = (CheckboxMenuItem) popup.getItem(i);
					if (mi.getName() != null) {
						logger.debug("The current Checkbox Item is named "
								+ mi.getLabel());
						if (mi.getLabel().equalsIgnoreCase(cache.getName())) {
							cache.InstallPrinter();
							cache.setActive(true);
							mi.setState(true);
						}
					}
				} catch (ClassCastException e) {
					// Not a check box, continue...
				}
			}
		}
	}

	private void getDefaultSet() {

		MenuItem prefs = new MenuItem("Preferences...");
		MenuItem about = new MenuItem("About MobilePrinting...");
		MenuItem exit = new MenuItem("Exit");

		ActionListener exitListener = new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				logger.debug("Exiting... ");
				// TODO Un-install printer if exit is pressed
				System.exit(0);
			}
		};

		ActionListener aboutListener = new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				logger.debug("About Menu...");
				// TODO Open an about page if About is pressed
			}
		};

		ActionListener prefListener = new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				logger.debug("Opening Preferences Menu...");
				PreferencesPanel.createAndShowGUI();
			}
		};

		about.addActionListener(aboutListener);
		exit.addActionListener(exitListener);
		prefs.addActionListener(prefListener);

		popup.add(prefs);
		popup.addSeparator();
		popup.add(about);
		popup.add(exit);
	}

	private void setAllPrintersInactive() {

		for (int i = 0; i < popup.getItemCount(); i++) {
			try {
				CheckboxMenuItem mi = (CheckboxMenuItem) popup.getItem(i);
				mi.setState(false);
			} catch (ClassCastException e) {
			}
			// MenuItem mi = popup.getItem(i);
			// mi.setFont(f);
		}
		for (Printer p : printers) {
			p.setActive(false);
		}

	}

}
